import { Module } from '@nestjs/common'
import { TerminusModule } from '@nestjs/terminus'
import { TypeOrmModule } from '@nestjs/typeorm'
import { ScheduleModule } from '@nestjs/schedule'
import { ConfigModule, ConfigService } from '@donews/nestjs-config'
import Joi from 'joi'
import { resolve } from 'path'

import { components, repositories } from './bootstrap'
import { AuthGuard } from '@/modules/guard'
import { APP_GUARD } from '@nestjs/core'
import { QueueModule } from 'nestjs-queue'

import * as entities from '@/entities'
import * as modules from '@/modules'
import * as controllers from '@/controller'
import * as services from '@/service'
import * as schedules from '@/schedule'

const configOption = {
    envFilePath: resolve(__dirname, '../config/config.yaml'),
}
const queueOption = {
    name: 'oa',
    connection: {
        redis: {
            host: '127.0.0.1',
            port: 8011,
            password: 'JCFkQYex4f',
        },
        prefix: 'oa-queue',
    },
}

@Module({
    imports: [
        TerminusModule,
        ScheduleModule.forRoot(),
        ConfigModule.forRoot(configOption),
        QueueModule.forRoot(queueOption),
        TypeOrmModule.forRootAsync({
            useFactory: (config: ConfigService) => {
                return {
                    type: 'mysql',
                    host: config.get('mysql.host', 'localhost'),
                    port: config.get('mysql.port', 8012),
                    username: config.get('mysql.username', 'root'),
                    password: 'JCFkQYex4f',
                    database: config.get('mysql.database', 'default'),
                    entities: [__dirname + '/entities/**/*.entity{.ts,.js}'],
                    synchronize: config.get('mysql.synchronize', false),
                    maxQueryExecutionTime: config.get('mysql.maxQueryExecutionTime', 1000),
                    logging: ['error', 'warn'],
                }
            },
            inject: [ConfigService],
            imports: [ConfigModule.forRoot(configOption)],
        }),
    ],
    controllers: components(controllers),
    providers: components(repositories(entities), modules, schedules, services, {
        provide: APP_GUARD,
        useClass: AuthGuard,
    }),
})
export class AppModule {}
